﻿using HandyControl.Controls;
using Kxx_Task.DNS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Handy_DNS.View.Pages
{
    /// <summary>
    /// ServicePage.xaml 的交互逻辑
    /// </summary>
    public partial class ServicePage : Page
    {
        public ServicePage()
        {
            InitializeComponent();

            Init();
        }

        #region 初始化
        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {
            new Task(() => {
                while (true)
                {
                    ServiceStatusUICtl();

                    Thread.Sleep(3000); 
                }
            }).Start();
        }
        #endregion

        /// <summary>
        /// 执行dos命令
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public string Execute(string command)
        {
            //string str = Console.ReadLine();
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;    //是否使用操作系统shell启动
            p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
            p.StartInfo.CreateNoWindow = false;//不显示程序窗口
            p.Start();//启动程序
            //向cmd窗口发送输入信息  + "&exit"
            p.StandardInput.WriteLine(command + "&exit");
            p.StandardInput.AutoFlush = true;
            //p.StandardInput.WriteLine("exit");
            //向标准输入写入要执行的命令。这里使用&是批处理命令的符号，表示前面一个命令不管是否执行成功都执行后面(exit)命令，如果不执行exit命令，后面调用ReadToEnd()方法会假死
            //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令，后者表示必须前一个命令执行失败才会执行后面的命令
            //获取cmd窗口的输出信息
            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();//等待程序执行完退出进程
            p.Close();
            return output;
        }

        /// <summary>
        /// 服务状态UI控制
        /// </summary>
        private void ServiceStatusUICtl()
        {
            this.Dispatcher.BeginInvoke(new Action(() => {
                if (DNSLoad.ISWindowsServiceInstalled(DNSLoad.serverName))
                {
                    btn_UnInstall.IsEnabled = true;
                    btn_Install.IsEnabled = false;

                    if (DNSLoad.IsWindowsServiceRunning(DNSLoad.serverName))
                    {
                        btn_Stop.IsEnabled = true;
                        btn_Start.IsEnabled = false;
                    }
                    else
                    {
                        btn_Start.IsEnabled = true;
                        btn_Stop.IsEnabled = false;
                    }
                }
                //服务不存在
                else
                {
                    btn_Install.IsEnabled = true;

                    btn_UnInstall.IsEnabled = false;
                    btn_Start.IsEnabled = false;
                    btn_Stop.IsEnabled = false;
                }
            }));
        }

        #region 操作
        /// <summary>
        /// 安装
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Install_Click(object sender, RoutedEventArgs e)
        {
            #region 验证
            if (DNSLoad.ISWindowsServiceInstalled(DNSLoad.serverName))
            {
                Growl.Error("服务已安装!");
                btn_Install.IsEnabled = false;
                return;
            }
            #endregion

            #region 命令执行
            try
            {
                string dosCommand = $"sc.exe create \"{DNSLoad.serverName}\" binpath=\"{AppDomain.CurrentDomain.BaseDirectory}DNS-BackGroundService.exe\" start= auto";
                string strRtn = Execute(dosCommand);
                Growl.Success(strRtn);
            }
            catch (Exception ex)
            {
                Growl.Error($"卸载失败，错误：{ex.Message}!");
            }
            #endregion
        }

        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Start_Click(object sender, RoutedEventArgs e)
        {
            #region 验证
            if (DNSLoad.IsWindowsServiceRunning(DNSLoad.serverName))
            {
                Growl.Error("服务已启动!");
                btn_Start.IsEnabled = false;
                return;
            }
            #endregion

            #region 命令执行
            try
            {
                string dosCommand = $"sc.exe start \"{DNSLoad.serverName}\"";
                string strRtn = Execute(dosCommand);
                Growl.Success(strRtn);
            }
            catch (Exception ex)
            {
                Growl.Error($"卸载失败，错误：{ex.Message}!");
            }
            #endregion
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Stop_Click(object sender, RoutedEventArgs e)
        {
            #region 验证
            if (!DNSLoad.IsWindowsServiceRunning(DNSLoad.serverName))
            {
                Growl.Error("服务不存在或已停止!");
                btn_Stop.IsEnabled = false;
                return;
            }
            #endregion

            #region 命令执行
            try
            {
                string dosCommand = $"sc.exe stop \"{DNSLoad.serverName}\"";
                string strRtn = Execute(dosCommand);
                Growl.Success(strRtn);
            }
            catch (Exception ex)
            {
                Growl.Error($"卸载失败，错误：{ex.Message}!");
            }
            #endregion
        }

        /// <summary>
        /// 卸载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_UnInstall_Click(object sender, RoutedEventArgs e)
        {
            #region 验证
            if (!DNSLoad.ISWindowsServiceInstalled(DNSLoad.serverName))
            {
                Growl.Error("服务不存在!");
                btn_UnInstall.IsEnabled = false;
                return;
            } 
            #endregion

            #region 命令执行
            try
            {
                string dosCommand = $"sc.exe delete \"{DNSLoad.serverName}\"";
                string strRtn = Execute(dosCommand);
                Growl.Success(strRtn);
            }
            catch (Exception ex)
            {
                Growl.Error($"卸载失败，错误：{ex.Message}!");
            } 
            #endregion
        }
        #endregion
    }
}
